package main

import (
	"encoding/json"
	"fmt"
	"github.com/google/shlex"
	"os/exec"
	"regexp"
	"strings"
)

func scrapeMultiPathInfo() []map[string]string {
	tempParsingData := make(map[string]string)
	pathParsingData := make(map[string]string)
	var parsedData []map[string]string
	var paths []map[string]string
	var pathsEmpty []map[string]string
	thisIsANewBlock := false

	multiathCmd := exec.Command("bash", "-c", "multipath -ll")
	cmdOut, _ := multiathCmd.Output()
	cmdOutLines := strings.Split(string(cmdOut), "\n")
	cmdOutLines = cmdOutLines[:len(cmdOutLines)-1]
	for _, line := range cmdOutLines {
		if byteMatchResult, _ := regexp.Match(`^\w`, []byte(line)); byteMatchResult {
			if byteMatchResult, _ := regexp.Match(`^size`, []byte(line)); byteMatchResult {
				a, _ := shlex.Split(line)
				tempParsingData["size"] = strings.Split(a[0], "=")[1]
				tempParsingData["features"] = strings.Split(a[1], "=")[1]
				tempParsingData["hwhandler"] = strings.Split(a[2], "=")[1]
				tempParsingData["write_permission"] = strings.Split(a[3], "=")[1]
			} else {
				thisIsANewBlock = true

				if len(tempParsingData) > 0 && thisIsANewBlock {
					parsedData = append(parsedData, tempParsingData)
					tempParsingData = make(map[string]string)
					thisIsANewBlock = false
				}

				if byteMatchResult, _ := regexp.Match(`^[\w]{33}`, []byte(line)); byteMatchResult {
					a, _ := shlex.Split(line)
					tempParsingData["wwid"] = a[0]
					tempParsingData["dm_device_name"] = a[1]
					tempParsingData["vendor"] = a[2]
				} else if byteMatchResult, _ := regexp.Match(`^.*\([\w]{33}\)`, []byte(line)); byteMatchResult {
					a, _ := shlex.Split(line)
					tempParsingData["alias"] = a[0]
					tempParsingData["wwid"] = strings.Trim(a[1], "()")
					tempParsingData["dm_device_name"] = a[2]
					tempParsingData["vendor"] = a[3]
				}
			}
		} else {
			if byteMatchResult, _ := regexp.Match(`.*-\+-`, []byte(line)); byteMatchResult {
				a, _ := shlex.Split(line)
				tempParsingData["scheduling_policy"] = strings.Split(a[1], "=")[1]
				tempParsingData["prio"] = strings.Split(a[2], "=")[1]
				tempParsingData["status"] = strings.Split(a[3], "=")[1]
				paths = pathsEmpty
			} else if byteMatchResult, _ := regexp.Match(`.*-`, []byte(line)); byteMatchResult {
				a, _ := shlex.Split(line)
				pathParsingData = make(map[string]string)
				pathParsingData["path"] = a[1]
				pathParsingData["devnode"] = a[2]
				pathParsingData["major:minor"] = a[3]
				pathParsingData["dm_status"] = a[4]
				pathParsingData["path_status"] = a[5]
				pathParsingData["online_status"] = a[6]
				paths = append(paths, pathParsingData)
				paths, _ := json.Marshal(paths)
				tempParsingData["paths"] = string(paths)
			}
		}
	}

	if len(tempParsingData) > 0 {
		parsedData = append(parsedData, tempParsingData)
		tempParsingData = make(map[string]string)
	}

	return parsedData
}

func main() {
	multiPathInfo := scrapeMultiPathInfo()
	for _, multipath := range multiPathInfo {
		fmt.Println(multipath["paths"])
	}
}
